import Element from './Element';

function createElement(type, props, children) {
  //通过实例化拿到一个vDom对象
  return new Element(type, props, children);
}

function render(vDom) {
  //根据标签名创建真实元素节点
  const {
    type,
    props,
    children
  } = vDom,
  el = document.createElement(type);

  // console.log(type);
  //ul

  // console.log(props);
  //{class: 'list', style: 'width: 300px; height: 300px; background-color: orange'}

  /**
   * console.log(children);
   * [
   *   {type: 'li', props: {…}, children: Array(1)},
   *   {type: 'li', props: {…}, children: Array(1)},
   *   {type: 'li', props: {…}, children: Array(1)}
   * ]
   */

  // console.log(el);
  //<ul></ul>

  //遍历每一个虚拟节点的标签属性
  for (let key in props) {
    /**
     * 给节点设置属性的函数
     * @param el 创建的真实节点
     * @param key 属性名
     * @param props[key] 属性值
     */

    //给每个真实节点的标签设置属性
    setAttrs(el, key, props[key]);

    //遍历嵌套的子标签
    children.map((c) => {
      // console.log(c);
      //{type: 'li', props: {…}, children: Array(1)}
      //{type: 'p', props: {…}, children: Array(1)}
      //...

      //有可能是元素节点/文本节点
      if (c instanceof Element) {
        //Element构造出来的是元素节点
        //深度递归渲染子标签
        c = render(c);
      } else {
        //文本节点
        c = document.createTextNode(c);
      }

      //将子元素节点或文本节点插入到父节点<ul></ul>里
      el.appendChild(c);

    });

    //render()返回一个设置好属性和递归后的子标签后的真实节点

    /**
     * console.log(el);
     * <ul class="list">
     *   <li class="item">
     *     <p class="text">第1个列表项</p>
     *   </li>
     *   <li class="item">
     *     <p class="text">第2个列表项</p>
     *   </li>
     *   <li class="item">
     *     <p class="text">第3个列表项</p>
     *   </li></ul>
     */

    return el;

  }

  // console.log(el);
  //<ul class="list" style="width: 300px; height: 300px; background-color: orange;"></ul>

}

/**
 * 给节点设置属性的函数
 * @param el 创建的真实节点
 * @param key 属性名
 * @param props[key] 属性值
 */
function setAttrs(node, prop, value) {
  switch (prop) {
    //针对input/textarea里面的value
    case 'value':
      if (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA') {
        node.value = value;
      } else {
        node.setAttribute(prop, value);
      }
      break;
      //针对style属性
    case 'style':
      node.style.cssText = value;
      break;
    default:
      node.setAttribute(prop, value);
      break;
  }
}

/**
 * 渲染页面
 * @param {*} rDom 真实DOM
 * @param {*} rootEl 根节点
 */
function renderDOM(rDom, rootEl) {
  rootEl.appendChild(rDom);
}

export {
  createElement,
  render,
  setAttrs,
  renderDOM
}